1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  package com.macvu.tiles.xmlDefinition;
63  
64  import org.apache.commons.digester.Digester;
65  import org.xml.sax.SAXException;
66  
67  import java.io.IOException;
68  import java.io.InputStream;
69  import java.net.URL;
70  
71  public class XmlCacheParser {
72  
73      /***
74       * Associated digester.
75       */
76      protected Digester digester;
77      /***
78       * Should we use a validating XML parser to read the configuration file.
79       * Default is <code>false</code>.
80       */
81      protected boolean validating = false;
82      /***
83       * The set of public identifiers, and corresponding resource names for
84       * the versions of the configuration file DTDs we know about.  There
85       * <strong>MUST</strong> be an even number of Strings in this list!
86       */
87      protected String registrations[] = {
88          
89          "-//Apache Software Foundation//DTD Tiles Configuration//EN",
90          "/org/apache/struts/resources/tiles-config_1_1.dtd",
91          "-//Apache Software Foundation//DTD Components Configuration//EN",
92          "/org/apache/struts/resources/tiles-config.dtd",
93          
94          "-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN",
95          "/org/apache/struts/resources/tiles-config_1_1.dtd",
96      };
97  
98      /***
99       * Constructor.
100      * Creates a digester parser and initializes syntax rules.
101      */
102     public XmlCacheParser() {
103         digester = new Digester();
104         digester.setValidating(validating);
105         digester.setNamespaceAware(true);
106         digester.setUseContextClassLoader(true);
107         
108         for (int i = 0; i < registrations.length; i += 2) {
109             URL url = this.getClass().getResource(registrations[i + 1]);
110             if (url != null) {
111                 digester.register(registrations[i], url.toString());
112             }
113         }
114         
115         initDigester(digester);
116     }
117 
118     /***
119      * Set digester validating flag.
120      */
121     public void setValidating(boolean validating) {
122         digester.setValidating(validating);
123     }
124 
125     /***
126      * Set digester detail level.
127      *
128      * @deprecated Use the commons-logging to set digester debug level.
129      */
130     public void setDetailLevel(int detailLevel) {
131     }
132 
133     /***
134      * Init digester for components syntax.
135      * This is an old set of rules, left for backward compatibility.
136      *
137      * @param digester Digester instance to use.
138      * @deprecated
139      */
140     private void initDigesterForComponentsDefinitionsSyntax(Digester digester) {
141         
142         String PACKAGE_NAME = "com.macvu.tiles.xmlDefinition";
143         String TILES_PACKAGE_NAME = "org.apache.struts.tiles.xmlDefinition";
144 
145         String DEFINITION_TAG = "component-definitions/definition";
146         String definitionHandlerClass = PACKAGE_NAME + ".XmlCacheDefinition";
147 
148         String PUT_TAG = DEFINITION_TAG + "/put";
149         String putAttributeHandlerClass = TILES_PACKAGE_NAME + ".XmlAttribute";
150 
151         String LIST_TAG = DEFINITION_TAG + "/putList";
152         String listHandlerClass = TILES_PACKAGE_NAME + ".XmlListAttribute";
153 
154         String ADD_LIST_ELE_TAG = LIST_TAG + "/add";
155 
156         
157         digester.addObjectCreate(DEFINITION_TAG, definitionHandlerClass);
158         digester.addSetProperties(DEFINITION_TAG);
159         digester.addSetNext(DEFINITION_TAG, "putDefinition", definitionHandlerClass);
160         
161         digester.addObjectCreate(PUT_TAG, putAttributeHandlerClass);
162         digester.addSetNext(PUT_TAG, "addAttribute", putAttributeHandlerClass);
163         digester.addSetProperties(PUT_TAG);
164         digester.addCallMethod(PUT_TAG, "setBody", 0);
165         
166         digester.addObjectCreate(LIST_TAG, listHandlerClass);
167         digester.addSetProperties(LIST_TAG);
168         digester.addSetNext(LIST_TAG, "addAttribute", putAttributeHandlerClass);
169         
170         
171         
172         digester.addObjectCreate(ADD_LIST_ELE_TAG, putAttributeHandlerClass);
173         digester.addSetNext(ADD_LIST_ELE_TAG, "add", putAttributeHandlerClass);
174         digester.addSetProperties(ADD_LIST_ELE_TAG);
175         digester.addCallMethod(ADD_LIST_ELE_TAG, "setBody", 0);
176     }
177 
178     /***
179      * Init digester in order to parse instances definition file syntax.
180      * Instances is an old name for "definition". This method is left for
181      * backwards compatibility.
182      *
183      * @param digester Digester instance to use.
184      * @deprecated
185      */
186     private void initDigesterForInstancesSyntax(Digester digester) {
187         
188         String PACKAGE_NAME = "org.apache.struts.tiles.xmlDefinition";
189         String INSTANCE_TAG = "component-instances/instance";
190         String instanceHandlerClass = PACKAGE_NAME + ".XmlDefinition";
191 
192         String PUT_TAG = INSTANCE_TAG + "/put";
193         String PUTATTRIBUTE_TAG = INSTANCE_TAG + "/putAttribute";
194         String putAttributeHandlerClass = PACKAGE_NAME + ".XmlAttribute";
195 
196         String LIST_TAG = INSTANCE_TAG + "/putList";
197         String listHandlerClass = PACKAGE_NAME + ".XmlListAttribute";
198 
199         String ADD_LIST_ELE_TAG = LIST_TAG + "/add";
200 
201         
202         digester.addObjectCreate(INSTANCE_TAG, instanceHandlerClass);
203         digester.addSetProperties(INSTANCE_TAG);
204         digester.addSetNext(INSTANCE_TAG, "putDefinition", instanceHandlerClass);
205         
206         digester.addObjectCreate(PUTATTRIBUTE_TAG, putAttributeHandlerClass);
207         digester.addSetProperties(PUTATTRIBUTE_TAG);
208         digester.addSetNext(PUTATTRIBUTE_TAG, "addAttribute", putAttributeHandlerClass);
209         
210         digester.addObjectCreate(PUT_TAG, putAttributeHandlerClass);
211         digester.addSetProperties(PUT_TAG);
212         digester.addSetNext(PUT_TAG, "addAttribute", putAttributeHandlerClass);
213         
214         digester.addObjectCreate(LIST_TAG, listHandlerClass);
215         digester.addSetProperties(LIST_TAG);
216         digester.addSetNext(LIST_TAG, "addAttribute", putAttributeHandlerClass);
217         
218         
219         
220         digester.addObjectCreate(ADD_LIST_ELE_TAG, putAttributeHandlerClass);
221         digester.addSetProperties(ADD_LIST_ELE_TAG);
222         digester.addSetNext(ADD_LIST_ELE_TAG, "add", putAttributeHandlerClass);
223     }
224 
225     /***
226      * Init digester for Tiles syntax.
227      * Same as components, but with first element = tiles-definitions
228      *
229      * @param digester Digester instance to use.
230      */
231     private void initDigesterForTilesDefinitionsSyntax(Digester digester) {
232         
233         String PACKAGE_NAME = "com.macvu.tiles.xmlDefinition";
234         String TILES_PACKAGE_NAME = "org.apache.struts.tiles.xmlDefinition";
235         String DEFINITION_TAG = "tiles-definitions/definition";
236         String definitionHandlerClass = PACKAGE_NAME + ".XmlCacheDefinition";
237 
238         String PUT_TAG = DEFINITION_TAG + "/put";
239         String putAttributeHandlerClass = TILES_PACKAGE_NAME + ".XmlAttribute";
240 
241         String CACHE_INFORMATION_TAG = DEFINITION_TAG + "/cacheInformation";
242         String cacheInformationHandlerClass = PACKAGE_NAME + ".XmlCacheInformation";
243 
244         String CACHE_ATTRIBUTE_TAG = CACHE_INFORMATION_TAG + "/key";
245         String cacheKeyHandlerClass = PACKAGE_NAME + ".XmlCacheAttribute";
246 
247         
248         
249         String LIST_TAG = "putList";
250         String DEF_LIST_TAG = DEFINITION_TAG + "/" + LIST_TAG;
251         String listHandlerClass = TILES_PACKAGE_NAME + ".XmlListAttribute";
252         
253         String ADD_LIST_ELE_TAG = "*/" + LIST_TAG + "/add";
254 
255         
256         digester.addObjectCreate(DEFINITION_TAG, definitionHandlerClass);
257         digester.addSetProperties(DEFINITION_TAG);
258         digester.addSetNext(DEFINITION_TAG, "putDefinition", definitionHandlerClass);
259         
260         
261         
262         
263         
264         digester.addObjectCreate(PUT_TAG, putAttributeHandlerClass);
265         digester.addSetNext(PUT_TAG, "addAttribute", putAttributeHandlerClass);
266         digester.addSetProperties(PUT_TAG);
267         digester.addCallMethod(PUT_TAG, "setBody", 0);
268         
269         
270         digester.addObjectCreate(DEF_LIST_TAG, listHandlerClass);
271         digester.addSetProperties(DEF_LIST_TAG);
272         digester.addSetNext(DEF_LIST_TAG, "addAttribute", putAttributeHandlerClass);
273         
274         
275         
276         digester.addObjectCreate(ADD_LIST_ELE_TAG, putAttributeHandlerClass);
277         digester.addSetNext(ADD_LIST_ELE_TAG, "add", putAttributeHandlerClass);
278         digester.addSetProperties(ADD_LIST_ELE_TAG);
279         digester.addCallMethod(ADD_LIST_ELE_TAG, "setBody", 0);
280 
281         
282         
283         String NESTED_LIST = "*/" + LIST_TAG + "/" + LIST_TAG;
284         digester.addObjectCreate(NESTED_LIST, listHandlerClass);
285         digester.addSetProperties(NESTED_LIST);
286         digester.addSetNext(NESTED_LIST, "add", putAttributeHandlerClass);
287 
288         
289         
290         
291         
292         
293         String ADD_WILDCARD = "*/item";
294         String menuItemDefaultClass = "org.apache.struts.tiles.beans.SimpleMenuItem";
295         digester.addObjectCreate(ADD_WILDCARD, menuItemDefaultClass, "classtype");
296         digester.addSetNext(ADD_WILDCARD, "add", "java.lang.Object");
297         digester.addSetProperties(ADD_WILDCARD);
298 
299         
300         String BEAN_TAG = "*/bean";
301         String beanDefaultClass = "org.apache.struts.tiles.beans.SimpleMenuItem";
302         digester.addObjectCreate(BEAN_TAG, beanDefaultClass, "classtype");
303         digester.addSetNext(BEAN_TAG, "add", "java.lang.Object");
304         digester.addSetProperties(BEAN_TAG);
305 
306         
307         digester.addSetProperty(BEAN_TAG + "/set-property", "property", "value");
308 
309         digester.addObjectCreate(CACHE_INFORMATION_TAG, cacheInformationHandlerClass);
310         digester.addSetProperties(CACHE_INFORMATION_TAG);
311         digester.addSetNext(CACHE_INFORMATION_TAG, "addCacheInformation", cacheInformationHandlerClass);
312 
313         digester.addObjectCreate(CACHE_ATTRIBUTE_TAG, cacheKeyHandlerClass);
314         digester.addSetProperties(CACHE_ATTRIBUTE_TAG);
315         digester.addSetNext(CACHE_ATTRIBUTE_TAG, "addCacheAttribute", cacheKeyHandlerClass);
316     }
317 
318     /***
319      * Init digester.
320      *
321      * @param digester Digester instance to use.
322      */
323     protected void initDigester(Digester digester) {
324         initDigesterForTilesDefinitionsSyntax(digester);
325         initDigesterForComponentsDefinitionsSyntax(digester);
326         initDigesterForInstancesSyntax(digester);
327     }
328 
329     /***
330      * Parse input reader and add encountered definitions to definitions set.
331      *
332      * @param in          Input stream.
333      * @param definitions Xml Definitions set to which encountered definition are added.
334      * @throws java.io.IOException      On errors during file parsing.
335      * @throws org.xml.sax.SAXException On errors parsing XML.
336      */
337     public void parse(InputStream in, XmlCacheDefinitionSet definitions) throws IOException, SAXException {
338         try {
339             
340             
341             digester.push(definitions);
342             
343             digester.parse(in);
344             in.close();
345         } catch (SAXException e) {
346             
347             throw e;
348         }
349 
350     }
351 }